package com.dingding.common.core.im.util;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.dingding.common.core.im.dto.SdkHttpResult;

public class HttpUtil {

	private static final String APPKEY = "RC-App-Key";
	private static final String NONCE = "RC-Nonce";
	private static final String TIMESTAMP = "RC-Timestamp";
	private static final String SIGNATURE = "RC-Signature";

	private static SSLContext sslCtx = null;
	static {

		try {
			sslCtx = SSLContext.getInstance("TLS");
			X509TrustManager tm = new X509TrustManager() {
				public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
				}

				public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
				}

				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			};
			sslCtx.init(null, new TrustManager[] { tm }, null);
		} catch (Exception e) {
			e.printStackTrace();
		}

		HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

			public boolean verify(String arg0, SSLSession arg1) {
				// TODO Auto-generated method stub
				return true;
			}

		});

		HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory());

	}

	// 设置body体
	public static void setBodyParameter(StringBuilder sb, HttpURLConnection conn) throws IOException {
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		out.writeBytes(sb.toString());
		out.flush();
		out.close();
	}

	// 添加签名header
	public static HttpURLConnection CreatePostHttpConnection(String appKey, String appSecret, String uri)
			throws MalformedURLException, IOException, ProtocolException {
		return CreatePostHttpConnection(appKey, appSecret, uri, "application/x-www-form-urlencoded");
	}

	// 创建HttpURLConnection 对象
	private static HttpURLConnection CreatePostHttpConnection(String appKey, String appSecret, String uri,
			String contentType) throws MalformedURLException, IOException, ProtocolException {
		// 随机数
		String nonce = String.valueOf(Math.random() * 1000000);
		// 时间戳
		String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
		// 系统分配的 App Secret、Nonce (随机数)、Timestamp (时间戳)三个字符串按先后顺序拼接成一个字符串
		StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
		// 进行 SHA1 哈希计算,得到数据签名
		String sign = CodeUtil.hexSHA1(toSign.toString());

		URL url = new URL(uri);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setUseCaches(false);
		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setRequestMethod("POST");
		conn.setInstanceFollowRedirects(true);
		conn.setConnectTimeout(30000);
		conn.setReadTimeout(30000);

		conn.setRequestProperty(APPKEY, appKey);
		conn.setRequestProperty(NONCE, nonce);
		conn.setRequestProperty(TIMESTAMP, timestamp);
		conn.setRequestProperty(SIGNATURE, sign);
		conn.setRequestProperty("Content-Type", contentType);

		return conn;
	}

	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		byte[] data = outStream.toByteArray();
		outStream.close();
		inStream.close();
		return data;
	}

	/**
	 * @Title: returnResult
	 * @Description: 返回获取Token的结果(成功或失败)
	 * @param conn 
	 * @throws Exception 
	 * @throws IOException  
	 * @author yuHaiQing
	 * @return SdkHttpResult    server sdk返回的封装
	 */
	public static SdkHttpResult returnResult(HttpURLConnection conn) throws Exception, IOException {

		String result;
		InputStream input = null;

		// 响应码(HTTP请求成功或失败)
		if (conn.getResponseCode() == 200) {
			input = conn.getInputStream();
		} else {
			input = conn.getErrorStream();
		}

		// 读取返回数据
		result = new String(readInputStream(input), "UTF-8");

		return new SdkHttpResult(conn.getResponseCode(), result);
	}
}
